use std::sync::Arc;
use cpal::traits::{DeviceTrait, HostTrait, StreamTrait};
use ringbuf::{HeapRb, Producer};
use super::resampler::HighQualityResampler;

pub struct AudioPlayer {
    pub(crate) _stream: cpal::Stream,
    pub(crate) producer: Producer<f32, Arc<HeapRb<f32>>>,
    pub(crate) input_sample_rate: u32,
    pub(crate) output_sample_rate: u32,
    pub(crate) input_channels: u32,
    pub(crate) output_channels: u32,
    pub(crate) resampler: Option<HighQualityResampler>,
}

impl AudioPlayer {
    pub fn new() -> Result<Self, Box<dyn std::error::Error>> {
        let host = cpal::default_host();
        let device = host.default_output_device().ok_or("没有找到默认音频输出设备")?;
        let config = device.default_output_config().map_err(|e| format!("无法获取默认音频配置: {}", e))?;
        log::info!("音频输出设备: {}, 配置: {:?}", device.name()?, config);
        let output_sample_rate = config.sample_rate().0;
        let output_channels = config.channels();
        let buffer_size = (output_sample_rate as f32 * 1.0) as usize;
        let ring_buffer = HeapRb::<f32>::new(buffer_size);
        let (producer, mut consumer) = ring_buffer.split();
        let stream = device.build_output_stream(
            &config.into(),
            move |data: &mut [f32], _| { for frame in data.iter_mut() { *frame = consumer.pop().unwrap_or(0.0); } },
            |err| log::error!("音频播放错误: {}", err),
            None,
        )?;
        stream.play()?;
        let resampler = if 8000 != output_sample_rate { Some(HighQualityResampler::new(8000, output_sample_rate, 1)?) } else { None };
        Ok(Self { _stream: stream, producer, input_sample_rate: 8000, output_sample_rate, input_channels: 1, output_channels: output_channels.into(), resampler })
    }

    pub fn update_config(&mut self, input_sample_rate: u32, input_channels: u32) -> Result<(), Box<dyn std::error::Error>> {
        if self.input_sample_rate != input_sample_rate || self.input_channels != input_channels {
            self.input_sample_rate = input_sample_rate;
            self.input_channels = input_channels;
            self.resampler = if input_sample_rate != self.output_sample_rate { Some(HighQualityResampler::new(input_sample_rate, self.output_sample_rate, input_channels as usize)?) } else { None };
        }
        Ok(())
    }

    pub fn play_audio(&mut self, samples: &[i16], sample_rate: u32, channels: u32) -> Result<(), Box<dyn std::error::Error>> {
        self.update_config(sample_rate, channels)?;
        let input_samples: Vec<f32> = samples.iter().map(|&s| s as f32 / 32768.0).collect();
        let resampled = if let Some(ref mut resampler) = self.resampler { resampler.process(&input_samples)? } else { input_samples };
        let output_samples = self.handle_channels(&resampled, channels);
        for &sample in &output_samples { if self.producer.push(sample).is_err() { break; } }
        Ok(())
    }

    fn handle_channels(&self, input_samples: &[f32], input_channels: u32) -> Vec<f32> {
        if input_channels == self.output_channels { return input_samples.to_vec(); }
        let frames = input_samples.len() / input_channels as usize;
        let mut output_samples = Vec::with_capacity(frames * self.output_channels as usize);
        for frame in 0..frames {
            for output_channel in 0..self.output_channels as usize {
                let sample = if output_channel < input_channels as usize { input_samples[frame * input_channels as usize + output_channel] } else if input_channels == 1 { input_samples[frame] } else { 0.0 };
                output_samples.push(sample);
            }
        }
        output_samples
    }
}


